package ar.com.osdepym.agregacionafip.parser;

import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

import ar.com.osdepym.agregacionafip.StringUtilities;
import ar.com.osdepym.agregacionafip.exceptions.FormatoFechaException;
import ar.com.osdepym.agregacionafip.exceptions.ParseoArchivoException;
import ar.com.osdepym.agregacionafip.modelfile.Detalle;

public class Parser {
private SimpleDateFormat formatoDelTexto = new SimpleDateFormat("yyyy-MM-dd");

	public void parserFila(String filaDeArchivo, CamposDeArchivo camposArchivo, Detalle detalle) throws FormatoFechaException, ParseoArchivoException {
		
		/*
		 *En este primer for se parsean del String (mensaje) los campos del HDR. 
		 */
		int pivote = 0;
		String campoMensaje ="";
		Field userField =null;
		//int longitud = camposArchivo.obtenerLongitud();
		for (Campo campo : camposArchivo.getCamposDetail()) {
			
			int pivoteHasta = pivote + campo.getLongitud();
			campoMensaje = filaDeArchivo.substring(pivote, pivoteHasta);
			
			try {
				userField = detalle.getClass().getDeclaredField(campo.getNombre());
				//System.out.println("Por setear el campo: " +campo.getNombre());
				this.setearAtributo(detalle, userField, campo, campoMensaje);
				//System.out.println("Se seteo el campo: " +campo.getNombre());
			} catch (ParseException e) {
				throw new FormatoFechaException();
			}catch (Exception e) {
				throw new ParseoArchivoException();
			} 
			pivote = pivoteHasta;				
		}
		
	}
	
	public String buildFila(Detalle nomina, CamposDeArchivo camposArchivo) {
		
		String fila = "";
		
		for (Campo campo : camposArchivo.getCamposDetail()) {
			
			fila = fila + this.getAtributo(nomina, campo);
							
		}
		return fila;
	}

	private void setearAtributo(Detalle detalle, java.lang.reflect.Field userField, Campo campo, String campoMensaje) throws IllegalArgumentException, IllegalAccessException, ParseException {
		
		boolean accesible = userField.isAccessible();
		userField.setAccessible(true);
		
		if("String".equals(campo.getTipo())){
			userField.set(detalle, campoMensaje);
		}
		else if("Integer".equals(campo.getTipo())){
			if(campoMensaje.trim().length() == 0)
				campoMensaje = StringUtilities.toRightAlignedFormat(campoMensaje.trim(), campo.getLongitud(), '0').toString();				
			Integer i = Integer.valueOf(campoMensaje);
			userField.set(detalle, i);
		}
		
		else if("Long".equals(campo.getTipo())){
			if(campoMensaje.trim().length() == 0) 
				campoMensaje = StringUtilities.toRightAlignedFormat(campoMensaje.trim(), campo.getLongitud(), '0').toString();
			Long i = Long.valueOf(campoMensaje);
			userField.set(detalle, i);
		}
		else if("Float".equals(campo.getTipo())){
			if(campoMensaje.trim().length() == 0) 
				campoMensaje = StringUtilities.toRightAlignedFormat(campoMensaje.trim(), campo.getLongitud(), '0').toString();
			String valor = campoMensaje.substring(0, campo.getEnteros())+"."+campoMensaje.substring(campo.getEnteros());
			Float f = Float.valueOf(valor);
			userField.set(detalle, f);
		}
		else if("Date".equals(campo.getTipo())){
			//El tipo date lo recibimos asi  "aaaa-mm-dd"
			
			String strFecha = campoMensaje;
			Date fecha = null;
			fecha = formatoDelTexto.parse(strFecha);
			userField.set(detalle, fecha);
		}else if("Boolean".equals(campo.getTipo())){
			if(campoMensaje.trim().length() == 0)
				campoMensaje = StringUtilities.toRightAlignedFormat(campoMensaje.trim(), campo.getLongitud(), 'N').toString();				
			Boolean v = campoMensaje.equals("S");
			userField.set(detalle, v);
		}else if("Boolean2".equals(campo.getTipo())){
			if(campoMensaje.trim().length() == 0)
				campoMensaje = StringUtilities.toRightAlignedFormat(campoMensaje.trim(), campo.getLongitud(), 'N').toString();				
			Boolean v = campoMensaje.equals("0");
			userField.set(detalle, v);
		}
		
		userField.setAccessible(accesible);
	}
	
	private String getAtributo(Detalle detalle, Campo campo){
		
		String campoString = "";
		java.lang.reflect.Field userField;
		try {
			userField = detalle.getClass().getDeclaredField(campo.getNombre());
			
			boolean accesible = userField.isAccessible();
			userField.setAccessible(true);
			
						
			if("String".equals(campo.getTipo())){
				String aux = userField.get(detalle).toString();
				campoString = StringUtilities.toRightAlignedFormat(aux, campo.getLongitud(), '0').toString();
			}
			else if("Integer".equals(campo.getTipo())){
				String aux = userField.get(detalle).toString();
				campoString = StringUtilities.toRightAlignedFormat(aux, campo.getLongitud(), '0').toString();
			}
			else if("Long".equals(campo.getTipo())){
				String aux = userField.get(detalle).toString();
				campoString = StringUtilities.toRightAlignedFormat(aux, campo.getLongitud(), '0').toString();
			}
			else if("Float".equals(campo.getTipo())){
				String aux =  userField.get(detalle).toString();
				
				BigDecimal big = new BigDecimal(aux);

				big = big.setScale(2, RoundingMode.HALF_UP);
				aux = big.toString().replace(".", "");
				campoString = StringUtilities.toRightAlignedFormat(aux, campo.getLongitud(), '0').toString();
			}
			else if("Date".equals(campo.getTipo())){
				//El tipo date lo recibimos asi  "aaaa-mm-dd"
				Date fecha = (Date) userField.get(detalle);
				campoString = formatoDelTexto.format(fecha);
			}
			else if("Boolean".equals(campo.getTipo())){
				Boolean v = (Boolean) userField.get(detalle);
				campoString = v ? "S" : "N"; 
			}
			else if("Boolean2".equals(campo.getTipo())){
				Boolean v = (Boolean) userField.get(detalle);
				campoString = v ? "0" : "1"; 
			}
			userField.setAccessible(accesible);
			
		} catch (SecurityException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (NoSuchFieldException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		return campoString;
		
	}
}
